package dkbta.ontology.elements.abstractions.interpolation;

import static dkbta.util.time.TimeUtils.convertMillisToTimeUnit;

import java.util.Arrays;

import dkbta.util.time.TimeInterval;
import dkbta.util.time.TimeUnit;

/**
 * A persistence table (part of a persistence function)
 * 
 * @author Uri Kanonov
 */
public class PersistenceTable{
	/**
	 * The maximum gaps according to the duration of the interval before (row) and the
	 * duration of the interval after (column)
	 */
	private final long[][] _table;

	/** The time unit, on which the persistence table is based */
	private final TimeUnit _timeUnit;

	/** The type of persistence table: positive-positive or negative-negative */
	@SuppressWarnings("unused")
	private final String _type;

	/**
	 * Constructs a persistence table
	 * 
	 * @param timeUnit The time unit, on which the persistence table is based
	 * @param type The type of persistence table: positive-positive or negative-negative
	 * @param table The maximum gaps according to the duration of the interval before
	 *        (row) and the duration of the interval after (column)
	 */
	public PersistenceTable(TimeUnit timeUnit, String type, long[][] table){
		_timeUnit = timeUnit;
		_type = type;
		_table = table;
	}

	/**
	 * Checks whether the two time intervals can be joined. This is done by obtaining the
	 * number of time units in the first interval's duration, and same for the second. The
	 * first represents a row and the latter a column into the gaps table. The two
	 * intervals can be joined if the gap between them is smaller or equal to the value in
	 * the table at those coordinates.
	 * 
	 * @param before The first interval
	 * @param after The second interval
	 * @return Whether the two time intervals can be joined
	 */
	public boolean canBeJoined(TimeInterval before, TimeInterval after){
		int beforeIndex = Math.min(_table.length - 1, (int)convertMillisToTimeUnit(before
				.getDuration(), _timeUnit));
		int afterIndex = Math.min(_table.length - 1, (int)convertMillisToTimeUnit(after
				.getDuration(), _timeUnit));
		long maximumGap = _table[beforeIndex][afterIndex];
		long actualGap = after.getStartTime() - before.getEndTime();

		return maximumGap >= actualGap;
	}

	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		for (long[] gaps : _table){
			sb.append("\r\n\t\t");
			sb.append(Arrays.toString(gaps));
		}
		return sb.toString();
	}
}
